package containers;


import net.mindview.util.Countries;

import java.util.*;

import static net.mindview.util.Print.print;
import static net.mindview.util.Print.printnb;

public class Lists {
    private static boolean b;
    private static String s;
    private static int i;
    private static Iterator<String> it;
    private static ListIterator<String> lit;

    /**
     * 包含每个List都可以执行的操作
     * @param a
     */
    public static void basicTest(List<String> a) {
        a.add(1, "x");//Add at location 1
        a.add("x");//Add at end
        //Add a collection:
        a.addAll(Countries.names(25));
        //Add a collection starting at location 3:
        a.addAll(3, Countries.names(25));
        b = a.contains("1");//Is it in there?
        //Is the entire collection in there?
        b = a.containsAll(Countries.names(25));
        //Lists allow random access, which is cheap for ArrayList, expensive for LinkedList:
        s = a.get(1);//Get (typed) object at location 1
        i = a.indexOf("1");//Tell index of object
        b = a.isEmpty();//Any elements inside>
        it = a.iterator();//Ordinary Iterator
        lit = a.listIterator();//ListIterator
        i = a.lastIndexOf("1");//Last match
        a.remove(1);//Remove location 1
        a.remove("3");//Remove this object
        a.set(1, "y");//Set location 1 to "y"
        //Keep everything that's in the argument
        //(the intersection of the two sets):
        a.retainAll(Countries.names(25));
        //Remove everything that's in the argument:
        a.removeAll(Countries.names(25));
        i = a.size();//How big is it?
        a.clear();//Remove all elements
    }

    /**
     * 使用Iterator遍历元素
     * @param a
     */
    public static void iterMotion(List<String> a) {
        ListIterator<String> it = a.listIterator();
        b = it.hasNext();
        b = it.hasPrevious();
        s = it.next();
        i = it.nextIndex();
        s = it.previous();
        i = it.previousIndex();
    }

    /**
     * 使用Iterator修改元素
     * @param a
     */
    public static void iterManipulation(List<String> a) {
        ListIterator<String> it = a.listIterator();
        it.add("47");
        //Must move to an element after add():
        it.next();
        //Remove the element after the newly produced one:
        it.remove();
        //Must move to an element after remove():
        it.next();
        //Change the element after deleted one:
        it.set("47");
    }

    /**
     * 查看List的操作效果:
     * @param a
     */
    public static void testVisual(List<String> a) {
        print(a);
        List<String> b = Countries.names(25);
        print("b = " + b);
        a.addAll(b);
        a.addAll(b);
        print(a);
        //Insert, remove, and replace elements
        //using a ListIterator:
        ListIterator<String> x = a.listIterator(a.size() / 2);
        x.add("one");
        print(a);
        print(x.next());
        x.remove();
        print(x.next());
        x.set("47");
        print(a);
        //Traverse the list backwards:
        x = a.listIterator(a.size());
        while (x.hasPrevious())
            printnb(x.previous() + " ");
        print();
        print("testVisual finished");
    }
    //There are some things that only LinkedLists can do:
    public static void testLinkedList() {
        LinkedList<String> ll = new LinkedList<>();
        ll.addAll(Countries.names(25));
        print(ll);
        //Treat it like a stack, pushing:
        ll.addFirst("one");
        ll.addFirst("two");
        print(ll);
        //Like "peeking" at the top of a stack:
        print(ll.getFirst());
        //Like popping a stack:
        print(ll.removeFirst());
        print(ll.removeFirst());
        //Treat it like a queue, pulling elements off the tail end:
        print(ll.removeLast());
        print(ll);
    }
    public static void main(String[] args) {
        //Make and fill a new list each time:
        basicTest(new LinkedList<>(Countries.names(25)));
        basicTest(new ArrayList<>(Countries.names(25)));
        iterMotion(new LinkedList<>(Countries.names(25)));
        iterMotion(new ArrayList<>(Countries.names(25)));
        iterManipulation(new LinkedList<>(Countries.names(25)));
        iterManipulation(new ArrayList<>(Countries.names(25)));
        testVisual(new LinkedList<>(Countries.names(25)));
        testLinkedList();
//        testIteratorSet(new LinkedList<>(Arrays.asList(1, 2, 3, 4)));
    }
    public static void testIteratorSet(List<Integer> list) {
        ListIterator<Integer> li = list.listIterator();
        print(li);
        print(list);
        li.set(47);
        print(li);
        print(list);
    }
}
